home *** CD-ROM | disk | FTP | other *** search
/ CYBER.XPO.95 / CYBER.XPO.95 (Arsenal Computer).ISO / popreq / amiga1 / a1000hks.lha / scsihdadaptor / scottdevice.asm < prev    next >
Assembly Source File  |  1980-01-03  |  21KB  |  834 lines

  1. * scottdisk.asm Copyright 1987 by Scott Turner ALL RIGHTS RESERVED
  2. *
  3. * This is a MOUNTable device driver for the MicroForge SCSI buss interface.
  4. * It may not chase yer mouse pointer around the screen, but I think someone
  5. * will find it useful :-). The strict license below is not because I'm an
  6. * asshole, but because there ARE assholes out there in the world. I've put
  7. * alot of effort into the driver and it is my sincere wish that it be made
  8. * available to ANYONE who wants it so long as the person or entity providing
  9. * it to them doesn't make a profit off it. BE WARNED, THIS IS NOT A 'PLAY'
  10. * LICENSE, I MEAN IT. (grrrr)
  11. *
  12. * This device driver supports 1 (ONE) SCSI buss device. This device can have
  13. * 2 (TWO) hard disk units attached to it. This driver is currently tuned for
  14. * use with an OMTI 5100 SCSI buss device.
  15. *
  16. * Please note that the OMTI needs a little breathing space after completion
  17. * of one command before beginning another. This driver is tuned to work on a
  18. * MC68000 or MC68010 running at the factory clock rate. If you jack the clock
  19. * rate or use an MC68020 you may need to re-tune this driver.
  20. *
  21. * Please note that this device driver uses the power LED as a disk activity
  22. * indicator.
  23. *
  24. * Formatting the hard disk seems to be a touchy area for most disk drivers
  25. * I've seen or heard about. This driver uses the SCSI command #4 to format
  26. * the drive if it is issued a format command for IO_OFFSET 0. I tried using
  27. * the OMTI format track command but it didn't really seem to format the
  28. * track because when I hit the un-formatted part of my test hard disk it
  29. * didn't format it. (Reads would return error $94) So I fell back to my
  30. * less than ideal solution of issuing the format command at offset 0. This
  31. * allows you to format the hard disk with the CLI FORMAT command, but none
  32. * of the other 'nifty' uses of a track by track formatter are available.
  33. * This may seem like a total bummer but then again more than a few controllers
  34. * can't format a single track. :) PLEASE NOTE: Unlike the MessyDOS FORMAT
  35. * command, there IS NO CHANCE of recovering data from the drive! So let's be
  36. * careful out there. ;)
  37. *
  38. * The MOUNT command can be used to partition the two hard disk drives into
  39. * smaller pieces. (See hints below)
  40. *
  41. * Here is a sample mountlist entry for a Seagate ST-4051:
  42. *    DH0:       Device = scottdisk.device
  43. *               Unit   = 0
  44. *               Flags  = 1
  45. *               Surfaces  = 5
  46. *               BlocksPerTrack = 17
  47. *               Reserved = 2
  48. *               Interleave = 0
  49. *               LowCyl = 0  ;  HighCyl = 976
  50. *               Buffers = 30
  51. *               BufMemType = 0
  52. *    #
  53. * Don't forget that the numbers used in the mountlist and used at the end of
  54. * this driver DO NOT HAVE TO MATCH. HOWEVER, the total SIZE given in the
  55. * mountlist MUST NOT exceed the size encoded at the end of this driver.
  56. *
  57. * To setup a system for operation:
  58. *    1. Configure the driver for your hard disk drive(s).
  59. *    2. Construct this driver and place the result in df0:devs/scottdisk.device
  60. *    3. Insert entry(s) into df0:devs/mountlist
  61. *    4. For each drive:
  62. *        A. mount <entryname>
  63. *        B. format drive <entryname> name <somename>
  64. *        C. Insert 'mount <entryname>' into your df0:s/startup-sequence
  65. *    5. Enjoy! :-)
  66. *
  67. * Hints:
  68. * If like me you hate using a slow 2nd floppy drive to copy disks, then setup
  69. * a partition on your hard disk using mountlist. Make it the same as an
  70. * amiga floppy: 11 sectors per track, 2 sides, 80 tracks. Then mount it and
  71. * you can diskcopy to/from a floppy to/from it! You can even call it DF1! :)
  72. * Rather than use the CLI AddBuffers command just tweak the 'Buffers =' line in
  73. * the mountlist entry.
  74. *
  75. * Please note that this driver could have tons of things done to it to improve
  76. * performance. And I am currently continuing work to make all sorts of changes
  77. * to this driver to improve performance. This version is being released at this
  78. * time so that others can get some use from it while I labor on.
  79. *
  80. * If you have questions/comments/requests concerning this source code, please
  81. * direct them in WRITING (no I don't mean via phone!) to:
  82. *
  83. * Scott Turner
  84. * L5 Computing
  85. * 12311 Maplewood Avenue
  86. * Edmonds, WA. 98020-1115 USA
  87. *
  88. * I may also be reached via:
  89. *
  90. * JST on GEnie
  91. * scotty@l5comp.UUCP or stride!l5comp!scotty
  92. *
  93. * I am NOT releasing this source code into the public domain. However, I here
  94. * by grant a license for distribution via AmigaDOS format 3.5" diskette or via
  95. * an online telecommunications medium provided that the party charges less than
  96. * the following to do so:
  97. *
  98. * USA $10 for a copy on an AmigaDOS 3.5" disk.
  99. * USA $10 an hour for 1200 baud connection at 18:00 PST from Seattle, WA USA.
  100. *
  101. * You may not use this source code to make object code if you intend to charge
  102. * anything above the above limits for the object code alone. ie you may not
  103. * sell the object code for more than the above stated limits for the source.
  104. *
  105. * I also hereby grant a license for converting this source code for the
  106. * following purposes:
  107. *    1. To change the hard disk drive parameters.
  108. *    2. To work with other SCSI buss interface cards.
  109. *    3. To work with other SCSI buss devices.
  110. *    4. Re-tune time delays.
  111. *
  112. * HOWEVER, under this license you may NOT:
  113. *    1. Remove my copyright.
  114. *    2. Modify or make additions to this license.
  115. *    3. Change the name of the device from 'scottdisk.device'.
  116. *    4. Change the limitation on charges for object code.
  117. *
  118. * (If you wonder if I'm egotistical, please note that 'scott' is the same
  119. * length as 'track'. This is handy for patching disk editors to use this device
  120. * driver rather than trackdisk.device.)
  121. *
  122. * I reserve all other rights. This source code is made available "AS IS" and I
  123. * make no warranties for it's fitness for any purpose.
  124. *
  125. *------------------------------------------------------------------------------
  126. *
  127. * I hate assembling 3,000 lines of include files. How about you?
  128. *
  129. * Definition of our base variables
  130. * This first part is cast in concrete
  131. LibNegSize    EQU    16
  132. LibPosSize    EQU    18
  133. OpenCount    EQU    32
  134. *
  135. * End of pre-defined lib-base structure, we can now do as we damn well please.
  136. CurUnit        EQU    34
  137. CurIOReq    EQU    36
  138. CurBlock    EQU    40
  139. CurBuffer    EQU    44
  140. NotifyIRQ    EQU    48
  141. NeedNotify    EQU    52
  142. DosBase        EQU    56
  143. BaseVarSize    EQU    60
  144. *
  145. * External references to EXEC
  146. _MakeLibrary    EQU    -6*14
  147. _Forbid        EQU    -6*22
  148. _Permit        EQU    -6*23
  149. _Cause        EQU    -6*30
  150. _AddPort    EQU    -6*59
  151. _PutMsg        EQU    -6*61
  152. _GetMsg        EQU    -6*62
  153. _ReplyMsg    EQU    -6*63
  154. _WaitPort    EQU    -6*64
  155. _OpenLibrary    EQU    -6*68
  156. _CloseLibrary    EQU    -6*69
  157. _AddDevice    EQU    -6*72
  158. *
  159. * External AmigaDOG reference
  160. _CreateProc    EQU    -6*23
  161. *
  162. * Address of SCSI port
  163. CtrlAddr    EQU    $EF7000
  164. *
  165. * Device version
  166. MajorVersion    EQU    33
  167. MinorVersion    EQU    1
  168. *
  169. * Number of blocks per track for BOTH DRIVES!!!
  170. BlocksPerTrack    EQU    17
  171. *
  172. * Driver header
  173. DriverIDString    DC.B    'ScottDisk 33.1 (23 May 1987)',13,10,0
  174. MatchTag    DC.W    $4AFC        ; RT_MATCHWORD
  175.         DC.L    MatchTag    ; RT_MATCHTAG
  176.         DC.L    EndOfDriver    ; RT_ENDSKIP
  177.         DC.B    1        ; RT_FLAGS
  178.         DC.B    MajorVersion    ; RT_VERSION
  179.         DC.B    3        ; RT_TYPE
  180.         DC.B    30        ; RT_PRI
  181.         DC.L    DeviceName    ; RT_NAME
  182.         DC.L    DriverIDString    ; RT_IDSTRING
  183.         DC.L    DriverInit    ; RT_INIT
  184. *
  185. * NOTE: This table is up here so the entries are positive in value. I don't
  186. * know if this is important or not.
  187. VectorTable    DC.W    -1    ; Entries are relative to VectorTable
  188.         DC.W    DeviceOpen-VectorTable        ; Open
  189.         DC.W    DeviceClose-VectorTable        ; Close
  190.         DC.W    DeviceNull-VectorTable        ; Expunge
  191.         DC.W    DeviceNull-VectorTable        ; NULL
  192.         DC.W    DeviceBeginIO-VectorTable    ; BeginIO
  193.         DC.W    DeviceNull-VectorTable        ; AbortIO
  194.         DC.W    -1    ; End of the table
  195.  
  196. DeviceOpen    CMPI.L    #1,D0        ; Unit number = 0 or 1?
  197.         BHI.S    0$
  198.         MOVE.L    D0,24(A1)    ; Then AOK
  199.         CLR.B    31(A1)        ; IO_ERR := 0
  200.         ADDQ.W    #1,32(A6)    ; Bump open count
  201.         RTS       
  202. *
  203. * Illegal unit # requested
  204. 0$        MOVE.B    #32,31(A1)    ; Return bad unit number error
  205.         RTS
  206.  
  207. DeviceClose    MOVEQ    #-1,D0
  208.         MOVE.L    D0,24(A1)    ; Kill unit #
  209.         MOVE.L    D0,20(A1)    ; Kill device pointer
  210. *
  211. * Dec open counter, but don't let it go negative
  212.         MOVE.W    OpenCount(A6),D0
  213.         BEQ.S    0$
  214.         SUBQ.W    #1,D0
  215.         MOVE.W    D0,OpenCount(A6)
  216. 0$        MOVEQ    #0,D0
  217.         RTS       
  218.  
  219. DeviceBeginIO    MOVEM.L    D1/A0-A1,-(A7)
  220.         CMPI.L    #1,24(A1)    ; Legal unit #?
  221.         BHI.S    3$
  222.         CLR.B    31(A1)        ; IO_ERR := 0
  223.         MOVE.B    29(A1),D0    ; Get command
  224.         SUBI.B    #12,D0        ; Standard command?
  225.         BLT.S    2$
  226.         CMPI.B    #4,D0        ; Special command?
  227.         BGE.S    2$
  228.         TST.B    D0
  229.         BNE.S    0$
  230. *
  231. * Record notify info
  232.         MOVE.L    40(A1),NotifyIRQ(A6)
  233.         SNE    NeedNotify(A6)
  234.         BRA.S    1$
  235. *
  236. * Return command packet now
  237. 3$        MOVE.B    #32,31(A1)    ; IO_ERR := bad unit you nerd!
  238. 0$        CLR.L    32(A1)
  239. 1$        BSET    #7,30(A1)
  240.         MOVE.B    #5,8(A1)
  241.         MOVEM.L    (A7)+,D1/A0-A1
  242.         MOVEQ    #0,D0
  243.         RTS       
  244.  
  245. *
  246. * Post command to the handler
  247. 2$        ANDI.B    #$7E,30(A1)    ; Clear status flags
  248.         LEA    OurPort,A0
  249.         MOVE.L    A6,-(A7)
  250.         MOVEA.L    4,A6
  251.         JSR    _PutMsg(A6)
  252.         MOVEA.L    (A7)+,A6
  253.         MOVEM.L    (A7)+,D1/A0-A1
  254.         MOVEQ    #0,D0
  255. DeviceNull    RTS       
  256.  
  257. DriverInitStructure
  258.         DC.B    %11100000
  259.         DC.B    0
  260.         DC.W    $8    ; LN_TYPE
  261.         DC.B    3    ; Device
  262.         DC.B    0    ; Pad
  263.         DC.B    %11000000
  264.         DC.B    0
  265.         DC.W    $A    ; LN_NAME
  266.         DC.L    DeviceName
  267.         DC.B    %11100000
  268.         DC.B    0
  269.         DC.W    $E    ; LIB_FLAGS
  270.         DC.B    6    ; Value for LIB_FLAGS, JustChanged, and please sum
  271.         DC.B    0    ; Padding
  272.         DC.B    %11000000
  273.         DC.B    0
  274.         DC.W    20    ; LIB_VERSION
  275.         DC.W    MajorVersion
  276.         DC.W    MinorVersion
  277.         DC.L    0
  278.  
  279. DogName        DC.B    'dos.library',0
  280. NewProcRecord    DC.L    DeviceName
  281.         DC.L    5
  282.         DC.L    SegList
  283.         DC.L    256
  284.  
  285. DriverInit    MOVEM.L    A2/A6,-(SP)
  286.         MOVEA.L    4,A6
  287. *
  288. * Build library structure
  289.         LEA    VectorTable,A0    ; Vectors
  290.         LEA    DriverInitStructure,A1    ; InitStructure
  291.         SUBA.L    A2,A2        ; InitRoutine, NULL we're already running!
  292.         MOVEQ    #BaseVarSize,D0    ; Our data seg size
  293.         JSR    _MakeLibrary(A6)
  294.         TST.L    D0
  295.         BEQ.S    TwilightZone    ; Go there if we didn't get created
  296. *
  297. * We were created
  298. * Save library base for the new process
  299.         MOVE.L    D0,LibraryBase
  300.         MOVEA.L    D0,A2
  301. *
  302. * Create a process for our handler
  303.         LEA    DogName(PC),A1
  304.         MOVEQ    #0,D0
  305.         JSR    _OpenLibrary(A6)
  306.         MOVE.L    D0,DosBase(A2)
  307.         MOVEA.L    D0,A2
  308. *
  309. * Create the handler process
  310.         MOVEM.L    NewProcRecord(PC),D1-D4
  311.         LSR.L    #2,D3        ; Linker won't do this :)
  312.         JSR    _CreateProc(A2)
  313.         SUBI.L    #$5C,D0        ; Convert DOS process to Exec process
  314.         MOVE.L    D0,PortTask    ; Patch message port
  315. *
  316. * Add our communications port to the system list
  317.         LEA    OurPort,A1
  318.         JSR    _AddPort(A6)
  319. *
  320. * Add us to the system device list
  321.         MOVEA.L    LibraryBase,A1    ; Position parameter for call
  322.         JSR    _AddDevice(A6)
  323.         MOVEQ    #1,D0        ; Indicate that we opened
  324.         MOVEM.L    (SP)+,A2/A6
  325.         RTS
  326.  
  327. TwilightZone    MOVEQ    #0,D0        ; Indicate that we didn't open
  328.         MOVEM.L    (SP)+,A2/A6
  329.         RTS
  330. *
  331. * Here begins the code for the handler process
  332.         CNOP    0,4    ; MUST be on longword boundary
  333.         DC.L    16    ; Segment length, value doesn't matter
  334. SegList        DC.L    0    ; Pointer to next segment (ie none)
  335. *
  336. * Initialize some registers with some handy values
  337.         MOVEA.L    4,A6
  338.         MOVEA.L    LibraryBase,A5
  339.         MOVEA.L    #CtrlAddr,A4
  340.         LEA    42(A4),A2    ; Status port-READ ONLY
  341.         LEA    44(A4),A3    ; Status port-WRITE ONLY
  342.         LEA    40(A4),A4    ; Data port-WRITE ONLY
  343. *
  344. * Offset 38 is the Data port-READ ONLY, but I ran out of regs...
  345. *
  346. * MicroForge SCSI status port bits
  347. *    Read  0 Reads as ONE        Write  0 ACK*
  348. *          1 MSG*                   1 ???
  349. *          2 CD*                   2 SEL*
  350. *          3 IO*                   3 ???
  351. *          4 REQ*                   4 ???
  352. *          5 Reads as ONE               5 ???
  353. *          6 Reads as ONE               6 ???
  354. *          7 Reads as ONE               7 ???
  355.         MOVEQ    #1,D3        ; Used for ACKing
  356.         MOVEQ    #4,D4        ; Used checking REQ
  357.         MOVEQ    #0,D5        ; Used for ACKing
  358. *
  359. * Configure the SCSI hard disk controller
  360.         JSR    _Forbid(A6)
  361.         BSR    InitController
  362.         JSR    _Permit(A6)
  363. *
  364. * Start waiting for commands on our port
  365.         CLR.W    NeedNotify(A5)
  366. LoopTop        TST.W    NeedNotify(A5)
  367.         BEQ.S    0$
  368.         MOVEA.L    NotifyIRQ(A5),A1
  369.         JSR    _Cause(A6)
  370.         CLR.W    NeedNotify(A5)
  371. 0$        LEA    OurPort,A0
  372.         JSR    _WaitPort(A6)
  373.         MOVE.L    D0,CurIOReq(A5)
  374.         LEA    OurPort,A0        ; Delink the message
  375.         JSR    _GetMsg(A6)
  376.         TST.L    CurIOReq(A5)
  377.         BEQ    LoopTop
  378. *
  379. * We have a packet, process it
  380.         BCHG    #1,$BFE001        ; Dim the LED
  381.         MOVEA.L    CurIOReq(A5),A0
  382.         MOVE.W    24+2(A0),D1        ; Get unit #
  383.         LSL.W    #5,D1            ; Convert to LUN
  384.         MOVE.B    D1,CurUnit(A5)        ; Store for use later
  385.         MOVE.L    44(A0),D0        ; Get IO_OFFSET
  386.         MOVEQ    #9,D1
  387.         LSR.L    D1,D0
  388.         MOVE.L    D0,CurBlock(A5)
  389.         MOVE.L    36(A0),D7        ; Get IO_LENGTH
  390.         LSR.L    D1,D7
  391.         MOVE.L    40(A0),CurBuffer(A5)    ; Move IO_BUFFER
  392.         MOVEQ    #0,D1            ; Get IO_COMMAND
  393.         MOVE.B    29(A0),D1
  394.         CMPI.W    #12,D1            ; In range?
  395.         BCC.S    CmdDone
  396.         ADD.W    D1,D1
  397.         JMP    DispatchTable(PC,D1.W)
  398.  
  399. MotorCmd    MOVE.L    D3,32(A0)    ;Return motor as ON
  400.         BRA.S    CmdDone
  401.  
  402. ReturnAOK    MOVE.L    D5,32(A0)
  403. CmdDone        BCHG    #1,$BFE001    ; Bring LED back up
  404.         MOVEA.L    CurIOReq(A5),A1    ; Send request back
  405.         JSR    _ReplyMsg(A6)
  406.         BRA    LoopTop        ; Back to loop top
  407.  
  408. DispatchTable    BRA    ReturnAOK    ;Invalid
  409.         BRA    ReturnAOK    ;Reset
  410.         BRA.S    ReadCmd        ;Read
  411.         BRA.S    WriteCmd    ;Write
  412.         BRA    ReturnAOK    ;Update buffers
  413.         BRA    ReturnAOK    ;Clear buffers
  414.         BRA    ReturnAOK    ;Stop
  415.         BRA    ReturnAOK    ;Start
  416.         BRA    ReturnAOK    ;Abort
  417.         BRA    MotorCmd    ;Motor
  418.         BRA    ReturnAOK    ;Seek
  419. *
  420. * Save one BRA by placing this here (Can I shave code or what? :)
  421. FormatCmd    TST.L    CurBlock(A5)
  422.         BNE.S    WriteCmd
  423.         SUBQ.W    #1,D7
  424.         BLT.S    1$
  425. 0$        MOVE.B    #4,CurrentCmd    ; Format track command
  426.         MOVE.B    #1,CurrentCmd+4
  427.         BSR    SendCmd
  428.         BSR    FinishUp
  429.         BPL.S    WriteCmd
  430. 1$        MOVEA.L    CurIOReq(A5),A0
  431.         MOVE.L    36(A0),32(A0)
  432.         BRA    CmdDone
  433.  
  434. ReadCmd        MOVE.B    #8,CurrentCmd
  435.         MOVE.B    D7,CurrentCmd+4
  436.         BEQ.S    1$
  437.         SUBQ.W    #1,D7
  438.         BSR.S    SendCmd
  439. 0$        BSR    ReadData
  440.         DBPL    D7,0$
  441.         BSR    FinishUp
  442. 1$        MOVEA.L    CurIOReq(A5),A0
  443.         MOVE.L    36(A0),32(A0)
  444.         BRA    CmdDone
  445.  
  446. WriteCmd    MOVE.B    #$A,CurrentCmd
  447.         MOVE.B    D7,CurrentCmd+4
  448.         BEQ.S    1$
  449.         SUBQ.W    #1,D7
  450.         BSR.S    SendCmd
  451. 0$        BSR.S    WriteData
  452.         DBPL    D7,0$
  453.         BSR    FinishUp
  454. 1$        MOVEA.L    CurIOReq(A5),A0
  455.         MOVE.L    36(A0),32(A0)
  456.         BRA    CmdDone
  457.  
  458. SendCmd        MOVE.L    CurBlock(A5),D0
  459.         MOVE.W    D0,CurrentCmd+2
  460.         SWAP.W    D0
  461.         OR.B    CurUnit(A5),D0
  462.         MOVE.B    D0,CurrentCmd+1
  463. *
  464. * Select SCSI device
  465.         MOVE.B    D3,(A4)
  466.         MOVE.B    D4,(A3)
  467. *
  468. * Wait for BSY
  469. 0$        MOVEQ    #%11111,D0
  470.         AND.B    (A2),D0
  471.         BEQ    0$
  472. *
  473. * Clear our out going bits (get off buss)
  474.         MOVE.B    D5,(A4)
  475.         MOVE.B    D5,(A3)
  476. *
  477. * Wait for SEL
  478. 1$        BTST    #2,(A2)
  479.         BEQ    1$
  480.         MOVEQ    #6-1,D0
  481.         LEA    CurrentCmd,A0
  482. *
  483. * Wait for REQ
  484. 2$        BTST    D4,(A2)
  485.         BEQ    2$
  486. *
  487. * Send command bytes
  488. 3$        MOVE.B    (A0)+,(A4)
  489.         MOVE.B    D3,(A3)
  490.         MOVE.B    D5,(A3)
  491.         DBF    D0,3$
  492.         MOVE.B    D5,(A4)
  493.         RTS
  494.  
  495. WriteData    MOVEA.L    CurBuffer(A5),A0
  496.         MOVEQ    #64-1,D0
  497. *
  498. * Wait for REQ
  499. 0$        BTST    D4,(A2)
  500.         BEQ    0$
  501. *
  502. * Check C/D if it's clear then AOK, else ERROR.
  503.         BTST    #2,(A2)
  504.         BNE.S    2$
  505. *
  506. * Write data to SCSI buss
  507. * NOTE: Un-winding past 8 doesn't return alot for the extra size.
  508. 1$        MOVE.B    (A0)+,(A4)    ;1
  509.         MOVE.B    D3,(A3)
  510.         MOVE.B    D5,(A3)
  511.         MOVE.B    (A0)+,(A4)    ;2
  512.         MOVE.B    D3,(A3)
  513.         MOVE.B    D5,(A3)
  514.         MOVE.B    (A0)+,(A4)    ;3
  515.         MOVE.B    D3,(A3)
  516.         MOVE.B    D5,(A3)
  517.         MOVE.B    (A0)+,(A4)    ;4
  518.         MOVE.B    D3,(A3)
  519.         MOVE.B    D5,(A3)
  520.         MOVE.B    (A0)+,(A4)    ;5
  521.         MOVE.B    D3,(A3)
  522.         MOVE.B    D5,(A3)
  523.         MOVE.B    (A0)+,(A4)    ;6
  524.         MOVE.B    D3,(A3)
  525.         MOVE.B    D5,(A3)
  526.         MOVE.B    (A0)+,(A4)    ;7
  527.         MOVE.B    D3,(A3)
  528.         MOVE.B    D5,(A3)
  529.         MOVE.B    (A0)+,(A4)    ;8
  530.         MOVE.B    D3,(A3)
  531.         MOVE.B    D5,(A3)
  532.         DBF    D0,1$
  533.         MOVE.B    D5,(A4)
  534. 2$        MOVE.L    A0,CurBuffer(A5)
  535.         TST.W    D0
  536.         RTS
  537.  
  538. ReadData    MOVEA.L    CurBuffer(A5),A0
  539.         MOVEQ    #64-1,D0
  540.         MOVEA.L    #CtrlAddr+38,A1
  541. *
  542. * Wait for REQ
  543. 0$        BTST    D4,(A2)
  544.         BEQ    0$
  545. *
  546. * Check C/D if it's clear then AOK, else ERROR.
  547.         BTST    #2,(A2)
  548.         BNE.S    2$
  549. *
  550. * Read data from SCSI buss
  551. * NOTE: Un-winding past 8 doesn't return alot for the extra size.
  552. 1$        MOVE.B    (A1),(A0)+    ;1
  553.         MOVE.B    D3,(A3)
  554.         MOVE.B    D5,(A3)
  555.         MOVE.B    (A1),(A0)+    ;2
  556.         MOVE.B    D3,(A3)
  557.         MOVE.B    D5,(A3)
  558.         MOVE.B    (A1),(A0)+    ;3
  559.         MOVE.B    D3,(A3)
  560.         MOVE.B    D5,(A3)
  561.         MOVE.B    (A1),(A0)+    ;4
  562.         MOVE.B    D3,(A3)
  563.         MOVE.B    D5,(A3)
  564.         MOVE.B    (A1),(A0)+    ;5
  565.         MOVE.B    D3,(A3)
  566.         MOVE.B    D5,(A3)
  567.         MOVE.B    (A1),(A0)+    ;6
  568.         MOVE.B    D3,(A3)
  569.         MOVE.B    D5,(A3)
  570.         MOVE.B    (A1),(A0)+    ;7
  571.         MOVE.B    D3,(A3)
  572.         MOVE.B    D5,(A3)
  573.         MOVE.B    (A1),(A0)+    ;8
  574.         MOVE.B    D3,(A3)
  575.         MOVE.B    D5,(A3)
  576.         DBF    D0,1$
  577. 2$        MOVE.L    A0,CurBuffer(A5)
  578.         TST.W    D0
  579.         RTS
  580.  
  581. FinishUp
  582. *
  583. * Wait for C/D
  584. 0$        BTST    #3,(A2)
  585.         BEQ    0$
  586.  
  587. *
  588. * Wait for REQ
  589. 1$        BTST    D4,(A2)
  590.         BEQ    1$
  591.  
  592. *
  593. * Read completion status byte
  594.         MOVE.B    CtrlAddr+38,D0
  595.         MOVE.B    D3,(A3)
  596.         MOVE.B    D5,(A3)
  597. *
  598. * Wait for MSG
  599. 2$        BTST.B    D3,(A2)
  600.         BEQ    2$
  601.  
  602. *
  603. * Wait for REQ
  604. 3$        BTST    D4,(A2)
  605.         BEQ    3$
  606.  
  607. *
  608. * ACK the completion message byte
  609.         MOVE.B    D3,(A3)
  610.         MOVE.B    D5,(A3)
  611.  
  612. *
  613. * Did an error occur?
  614.         BTST    D3,D0
  615.         BNE.S    Error
  616. *
  617. * A little delay for when we're good...
  618.         MOVEQ    #$10,D0
  619. 9$        DBF    D0,9$
  620. *
  621. * Return normal completion
  622.         MOVEQ    #0,D0
  623.         RTS       
  624. *
  625. * Error occured in command
  626. * Send command #3 to get reason for error
  627. Error        MOVE.B    #3,CurrentCmd
  628.         CLR.B    CurrentCmd+4
  629.         CLR.L    CurBlock(A5)
  630. *
  631. * OMTI needs time to think before we ask for error sense data.
  632.         MOVEQ    #$7F,D0
  633. 9$        DBF    D0,9$
  634.  
  635.         BSR    SendCmd
  636.         MOVEQ    #4-1,D0
  637.         LEA    ErrBuffer,A0
  638.         MOVEA.L    #CtrlAddr+38,A1
  639. *
  640. * Wait for REQ
  641. 0$        BTST    D4,(A2)
  642.         BEQ    0$
  643. *
  644. * Check C/D if it's clear then AOK, else ERROR
  645.         BTST    #2,(A2)
  646.         BNE.S    2$
  647. *
  648. * Read data from SCSI buss
  649. 1$        MOVE.B    (A1),(A0)+
  650.         MOVE.B    D3,(A3)
  651.         MOVE.B    D5,(A3)
  652.         DBF    D0,1$
  653.         MOVE.B    D5,(A4)
  654.         BSR.S    TossStatus
  655. *
  656. * Take the data returned and feed it to the user
  657.         MOVEA.L    CurIOReq(A5),A0
  658.         MOVE.B    ErrBuffer,D0
  659.         MOVE.B    D0,$CF        ; "back door" to get I/O result
  660.         MOVE.B    D0,31(A0)    ; Return SCSI error code
  661.         MOVEQ    #-1,D0
  662.         RTS
  663. *
  664. * Ooops, we had an error getting the error info.
  665. * BTW, this is most likely because the delay above needs tweaking.
  666. 2$        BSR.S    TossStatus
  667.         MOVE.B    #20,31(A0)    ; Return some kind of error :)
  668.         MOVEQ    #-1,D0
  669.         RTS
  670.  
  671. TossStatus
  672. *
  673. * Wait for C/D
  674. 0$        BTST    #3,(A2)
  675.         BEQ    0$
  676.  
  677. *
  678. * Wait for REQ
  679. 1$        BTST    D4,(A2)
  680.         BEQ    1$
  681.  
  682. *
  683. * Read completion status byte
  684.         MOVE.B    D3,(A3)
  685.         MOVE.B    D5,(A3)
  686. *
  687. * Wait for MSG
  688. 2$        BTST.B    D3,(A2)
  689.         BEQ    2$
  690.  
  691. *
  692. * Wait for REQ
  693. 3$        BTST    D4,(A2)
  694.         BEQ    3$
  695.  
  696. *
  697. * ACK the completion message byte
  698.         MOVE.B    D3,(A3)
  699.         MOVE.B    D5,(A3)
  700.         RTS
  701.  
  702. InitController    LEA    InitCmd,A0
  703.         BSR.S    SendICmd
  704.         LEA    InitData,A0
  705.         BSR.S    SendInitData
  706.  
  707. *
  708. * Wait for OMTI to get with it
  709.         MOVEQ    #$10,D0
  710. 0$        DBF    D0,0$
  711.  
  712.         LEA    InitCmd1,A0
  713.         BSR.S    SendICmd
  714.         LEA    InitData1,A0
  715.         BRA.S    SendInitData
  716.  
  717. SendICmd    MOVE.B    D3,(A4)
  718.         MOVE.B    D4,(A3)
  719. 0$        MOVEQ    #%11111,D0
  720.         AND.B    (A2),D0
  721.         BEQ    0$
  722.         MOVE.B    D5,(A4)
  723.         MOVE.B    D5,(A3)
  724. 1$        BTST    #2,(A2)
  725.         BEQ    1$
  726.         MOVEQ    #6-1,D0
  727. 2$        BTST    D4,(A2)
  728.         BEQ    2$
  729. 3$        MOVE.B    (A0)+,(A4)
  730.         MOVE.B    D3,(A3)
  731.         MOVE.B    D5,(A3)
  732.         DBF    D0,3$
  733.         MOVE.B    D5,(A4)
  734.         RTS
  735.  
  736. SendInitData    MOVEQ    #10-1,D0
  737. 0$        BTST    D4,(A2)
  738.         BEQ    0$
  739. 1$        MOVE.B    (A0)+,(A4)
  740.         MOVE.B    D3,(A3)
  741.         MOVE.B    D5,(A3)
  742.         DBF    D0,1$
  743.         MOVE.B    D5,(A4)
  744.         BRA    TossStatus
  745.  
  746.         DATA
  747. *
  748. * NOTE: I use a DATA section so that I can reach some of these variables via
  749. * absolute addressing. I COULD hang them off (A5) but it was just simpler to
  750. * hack them in down here as I needed them...
  751. DeviceName    DC.B    'scottdisk.device',0
  752.         CNOP    0,4
  753. LibraryBase    DC.L    0
  754. OurPort        DC.L    0
  755.         DC.L    0
  756.         DC.B    4
  757.         DC.B    0
  758.         DC.L    DeviceName
  759.         DC.B    0
  760.         DC.B    24
  761. PortTask    DC.L    0    ;TaskHandle
  762. LH1        DC.L    LH2
  763. LH2        DC.L    0
  764.         DC.L    LH1
  765.         DC.B    5
  766.         DC.B    0
  767.  
  768. CurrentCmd    DC.B    0,0,0,0,1,0
  769.  
  770. ErrBuffer    DC.L    0
  771.  
  772. InitCmd        DC.B    $C2,0,0,0,0,0
  773. InitCmd1    DC.B    $C2,$20,0,0,0,0
  774. *
  775. * The tables below are sent to the controller to configure it for the drive
  776. * attached to it. Do not change the sector size from 512 bytes!!!!
  777. *
  778. * Some global data about these values for the OMTI 5100 controller:
  779. * Step pulse width:
  780. * 00 thru 05    5us
  781. * 06 thru 08    7.8us
  782. * 09 thru 0B    10.6us
  783. * 0C thru 0E    13.4us
  784. * etc....
  785. *
  786. * Step period:
  787. * Value * 50us with value 0 yielding 9us rather than 0us :).
  788. *
  789. * Number of heads:
  790. * This value must be one less than the number of heads. If the drive has 5
  791. * heads then enter 4.
  792. *
  793. * Number of cylinders:
  794. * This value must be one less than the number of cylinders. If the drive has
  795. * 977 cylinders then enter 976.
  796. *
  797. * Bytes 7 and 8:
  798. * Are used to set the precomp and reduced write current starting points.
  799. * Reduced write is based on the 8 bits in byte 7. If byte 7 equals 0 or 1 then
  800. * reduced write current is disabled. Otherwise it starts at the cylinder
  801. * indicated by the value of byte 7.
  802. * Write precompensation is based on a 10 bit value made up from the 8 bits in
  803. * byte 7 and the lower 2 bits in byte 8. The two bits from byte 8 are tacked
  804. * onto the left of the bits from byte 7 to make the 10 bit value. If this 10
  805. * bit value is 0 then precomp is disabled. If this 10 bit value is 1 then
  806. * precomp is applied to ALL cylinders. Any other value indicates the cylinder
  807. * to start precomp on.
  808. *
  809. * Init data for drive 0
  810. InitData    DC.B    0    ; Step pulse width
  811.         DC.B    0    ; Step period
  812.         DC.B    0    ; Step mode
  813.         DC.B    5    ; Number of heads
  814.         DC.W    627    ; Number of cylinders
  815.         DC.W    0    ; Bytes 7 and 8 (see above)
  816.         DC.B    BlocksPerTrack
  817.         DC.B    0    ; Reserved
  818. *
  819. * Init data for drive 1
  820. InitData1    DC.B    0    ; Step pulse width
  821.         DC.B    0    ; Step period
  822.         DC.B    0    ; Step mode
  823.         DC.B    3    ; Number of heads
  824.         DC.W    611    ; Number of cylinders
  825.         DC.W    0    ; Bytes 7 and 8 (see above)
  826.         DC.B    BlocksPerTrack
  827.         DC.B    0    ; Reserved
  828. *
  829. * End driver on a long word boundary
  830.         CNOP    0,4
  831. EndOfDriver
  832.  
  833.         END
  834.